package com.k.usbupdate.util

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.provider.Settings
import android.util.Log
import android.widget.Toast
import androidx.core.content.FileProvider
import java.io.File

object UpdateUtil {

    val TAG = "UpdateUtil"

    fun setLogShow(isShow: Boolean) {
        ULogUtil.isShow = isShow
    }

    /**
     * 去更新
     */
    fun goUpdate(activity: Activity) {
        // 获取USB设备路径
        val dirList = OTGUtil.getUsbDir(activity)
        if (dirList.size == 0) {
            Toast.makeText(activity, "未读取到U盘", Toast.LENGTH_SHORT).show()
            return
        } else {
            // 获取需要更新的APK路径
            val apkList = OTGUtil.findUpdateApkPaths(dirList)
            ULogUtil.e("APK路径：" + apkList.toString())

            if (apkList.size > 0) { // 有更新的APK

                // 获取当前的版本号
                val currentVersion = getAppVersion(activity)
                val updateApkVersion = getApkVersionCodeFroPath(activity, apkList[0])

                val currentPackage = getPackageName(activity)
                val updateApkPackage = getApkPackageNameFroPath(activity, apkList[0])

                ULogUtil.e("currentVersion:" + currentVersion)
                ULogUtil.e("updateApkVersion:" + updateApkVersion)
                ULogUtil.e("currentPackage:" + currentPackage)
                ULogUtil.e("updateApkPackage:" + updateApkPackage)

                if (!currentPackage.equals(updateApkPackage)) {
                    Toast.makeText(activity, "更新失败，包名不一致", Toast.LENGTH_SHORT).show()
                    return
                }

                if (currentVersion > updateApkVersion!!) {
                    Toast.makeText(
                        activity,
                        "更新失败，apk版本小于当前安装的版本",
                        Toast.LENGTH_SHORT
                    ).show()
                    return
                }


                val finalPath = UFileUtil.copyFileFromUsbToDownload(activity, apkList[0])
                if (finalPath == null) {
                    Toast.makeText(activity, "更新失败，文件复制失败", Toast.LENGTH_SHORT).show()
                    return
                }

                ULogUtil.e("文件路径：" + finalPath)
                installApk(activity, finalPath) // 更新APK
            } else {
                Toast.makeText(activity, "没有找到U盘中的apk", Toast.LENGTH_SHORT).show()
            }
        }
    }

    /**
     * 获取当前App的版本号
     *
     * @param context
     * @return
     */
    fun getAppVersion(context: Context): Long {
        var version: Long = 0
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
            val packageManager = context.packageManager
            try {
                val packageInfo = packageManager.getPackageInfo(context.packageName, 0)
                version = packageInfo.versionCode.toLong()
            } catch (e: Exception) {
                e.printStackTrace()
            }
        } else {
            val packageManager = context.packageManager
            try {
                val packageInfo = packageManager.getPackageInfo(context.packageName, 0)
                version = packageInfo.longVersionCode
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
        return version
    }


    /**
     * 获取当前应用包名
     *
     * @param context
     * @return
     */
    fun getPackageName(context: Context): String? {
        return context.packageName
    }

    /**
     * 获取app文件的包名
     *
     * @param context
     * @param apkPath
     * @return
     */
    fun getApkPackageNameFroPath(context: Context, apkPath: String): String? {
        Log.i(TAG, "apkPath:$apkPath")
        if (fileExists(apkPath)) {
            val pm = context.packageManager
            val info = pm.getPackageArchiveInfo(apkPath, PackageManager.GET_ACTIVITIES)
            if (info != null) {
                val appInfo = info.applicationInfo
                //                String packageName = appInfo.packageName;  //得到安装包名称
//                String version = info.versionName;//获取安装包的版本号
                return try {
                    Log.i(TAG, appInfo?.packageName ?: "--")
                    appInfo?.packageName
                } catch (e: OutOfMemoryError) {
                    e.printStackTrace()
                    null
                }
            }
            return null
        }
        Log.i(TAG, "appNameApk:" + null)
        return null
    }

    /**
     * 获取app版本号
     *
     * @param context
     * @param apkPath
     * @return
     */
    fun getApkVersionCodeFroPath(context: Context, apkPath: String): Long? {
        var version: Long = 0
        if (fileExists(apkPath)) {
            val pm = context.packageManager
            val info = pm.getPackageArchiveInfo(apkPath, PackageManager.GET_ACTIVITIES)
            if (info != null) {
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
                    try {
                        version = info.versionCode.toLong()
                    } catch (e: Exception) {
                        e.printStackTrace()
                    }
                } else {
                    try {
                        version = info.longVersionCode
                    } catch (e: Exception) {
                        e.printStackTrace()
                    }
                }
            }
        }
        Log.i(TAG, "version:$version")
        return version
    }


    /**
     * 获取当前应用包名
     *
     * @param context
     * @return
     */
    fun getApkName(context: Context): String? {
        var appName: String? = null
        val packageManager = context.packageManager
        try {
            val packageInfo = packageManager.getPackageInfo(context.packageName, 0)
            appName = packageInfo.packageName
        } catch (e: Exception) {
            e.printStackTrace()
        }
        Log.i(TAG, "appNameCurrent:$appName")
        return appName
    }


    /**
     * 文件是否存在
     *
     * @param filePath
     * @return
     */
    fun fileExists(filePath: String): Boolean {
        val file = File(filePath)
        return if (file.exists()) {
            Log.i(TAG, "存在:$filePath")
            true
        } else {
            Log.i(TAG, "不存在:$filePath")
            false
        }
    }

    fun installApk(context: Activity, path: String) {
        val REQUEST_CODE_UNKNOWN_APP = 88
        Log.i(TAG, "安装路径==$path")
        val file = File(path)
        if (file.exists()) {
            Log.i(TAG, "下载的文件存在：" + file.length())
            val installApkIntent = Intent()
            installApkIntent.action = Intent.ACTION_VIEW
            installApkIntent.addCategory(Intent.CATEGORY_DEFAULT)
            installApkIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
            //适配8.0需要有权限
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                Log.i(TAG, "8.0以上安装")
                val hasInstallPermission = context.packageManager.canRequestPackageInstalls()
                if (hasInstallPermission) {
                    //安装应用
                    installApkIntent.setDataAndType(
                        FileProvider.getUriForFile(
                            context.applicationContext, context.packageName + ".fileProvider", file
                        ), "application/vnd.android.package-archive"
                    )
                    installApkIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                    if (context.packageManager.queryIntentActivities(
                            installApkIntent, 0
                        ).size > 0
                    ) {
                        context.startActivity(installApkIntent)
                    }
                } else {
                    //跳转至“安装未知应用”权限界面，引导用户开启权限
                    val selfPackageUri = Uri.parse("package:" + context.packageName)
                    val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, selfPackageUri)
                    context.startActivityForResult(intent, REQUEST_CODE_UNKNOWN_APP)
                }
            } else {
                Log.i(TAG, "8.0以下安装")
                if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {

                    val uri = FileProvider.getUriForFile(
                        context, context.packageName + ".fileprovider", file
                    )

                    Log.i(TAG, "uri:" + uri.toString())
//                    installApkIntent.setDataAndType(
//                        FileProvider.getUriForFile(
//                            context.applicationContext,
//                            context.packageName + ".fileProvider",
//                            file
//                        ), "application/vnd.android.package-archive"
//                    )

                    installApkIntent.setDataAndType(
                        uri, "application/vnd.android.package-archive"
                    )

                    installApkIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                } else {
                    installApkIntent.setDataAndType(
                        Uri.fromFile(file), "application/vnd.android.package-archive"
                    )
                }
                if (context.packageManager.queryIntentActivities(installApkIntent, 0).size > 0) {
                    context.startActivity(installApkIntent)
                }
            }
        } else {
            Log.i(TAG, "文件不存在")
        }
    }

    fun updateApk(context: Context, filePath: String) {
        val apkFile = File(filePath)

        if (apkFile.exists()) {
            val uri: Uri = FileProvider.getUriForFile(
                context,
//                "com.your.package.name.fileprovider",
//                "com.hj.offlinecab.fileprovider",
                context.packageName + ".fileprovider", apkFile
            )

            val intent = Intent(Intent.ACTION_VIEW).apply {
                setDataAndType(uri, "application/vnd.android.package-archive")
                addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            }
            context.startActivity(intent)
        } else {
            Toast.makeText(context, "文件不存在", Toast.LENGTH_SHORT).show()
        }
    }

    /**
     * file --> uri
     *
     * @param context
     * @param file
     * @return
     */
    fun getUriFromFile(context: Context?, file: File?): Uri? {
        if (context == null || file == null) {
            throw NullPointerException("上下文或文件为空")
        }

        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            FileProvider.getUriForFile(
                context, "${context.packageName}.fileprovider", file
            )
        } else {
            Uri.fromFile(file)
        }
    }
}